//
// File:	EntityDataMap.hpp
// Author:	Thomas TISSOT-DUPONT
// Login:	<thomas.tissotdupont@free.fr>
//
// Created:	22/04/2010 at 23:23:46
// Purpose:	
//
#ifndef ENTITYDATAMAP_HPP
#define ENTITYDATAMAP_HPP

#include <map>
#include <string>
#include "Variant.hpp"

//------------------------------------------------------------------
// DataMapField Class
//------------------------------------------------------------------
class DataMapField
{
public:
							DataMapField();
							DataMapField(const DataMapField &);
public:
	void					operator()(const Variant &);
	DataMapField			&operator=(const DataMapField &);
	template <typename T>
	static DataMapField		Create(T &);

private:
	template <typename T>
	void					Write(const Variant &);

private:
	void					(DataMapField::*m_pFnWriter)(const Variant &);
	void					*m_pVariable;
};

//------------------------------------------------------------------
// DataMapField Implementation
//------------------------------------------------------------------
template <typename T>
DataMapField DataMapField::Create(T &variable)
{
	DataMapField field;
	field.m_pVariable = &variable;
	field.m_pFnWriter = &DataMapField::Write<T>;
	return field;
}

template <typename T>
void DataMapField::Write(const Variant &v)
{
	*static_cast<T *>(m_pVariable) = v;
}

//------------------------------------------------------------------
// EntityDataMap Class
//------------------------------------------------------------------
class EntityDataMap
{
public:
	template <typename T>
	void									AddField(const std::string &, T &, const Variant & = Variant());
	void									Write(const std::string &, const Variant &);

private:
	std::map<std::string, DataMapField>		m_fields;
};

//------------------------------------------------------------------
// EntityDataMap Implementation
//------------------------------------------------------------------
template <typename T>
void EntityDataMap::AddField(const std::string &name, T &variable, const Variant &v /* = Variant() */)
{
	m_fields[name] = DataMapField::Create(variable);
	Write(name, v);
}

#endif //!ENTITYDATAMAP_HPP
